home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / xvisrc.zip / CURSOR.C < prev    next >
C/C++ Source or Header  |  1992-07-28  |  4KB  |  147 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)cursor.c    2.2 (Chris & John Downey) 9/1/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     cursor.c
  14. * module function:
  15.     Deal with movement of the screen cursor - i.e. when the
  16.     logical cursor moves within a buffer, work out the new
  17.     position of the screen cursor within its window.
  18. * history:
  19.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  20.     Originally by Tim Thompson (twitch!tjt)
  21.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  22.     Heavily modified by Chris & John Downey
  23.  
  24. ***/
  25.  
  26. #include "xvi.h"
  27.  
  28. static    void    calc_position_in_line P((Xviwin *));
  29.  
  30. /*
  31.  * Update the window's variables which say where the cursor is.
  32.  * These are row, col and virtcol, curswant if w_set_want_col.
  33.  *
  34.  * We also update w_c_line_size, which is used in screen.c to
  35.  * figure out whether the cursor line has changed size or not.
  36.  */
  37. void
  38. cursupdate(win)
  39. Xviwin    *win;
  40. {
  41. #if 0
  42.     if (win->w_curs_new == FALSE) {
  43.         return;
  44.     }
  45. #endif
  46.     win->w_curs_new = FALSE;
  47.  
  48.     /*
  49.      * Calculate physical lines from logical lines.
  50.      */
  51.     win->w_row = cntplines(win, win->w_topline, win->w_cursor->p_line);
  52.     win->w_c_line_size = plines(win, win->w_cursor->p_line);
  53.  
  54.     /*
  55.      * Calculate new position within the line.
  56.      */
  57.     calc_position_in_line(win);
  58. }
  59.  
  60. /*
  61.  * The cursor has moved along by nchars within the current line.
  62.  * Updating it here saves the overhead of cursupdate().
  63.  */
  64. void
  65. curs_horiz(win, nchars)
  66. Xviwin    *win;
  67. int    nchars;
  68. {
  69.     /*
  70.      * For the moment, just completely recalculate the position
  71.      * in the line. More optimisation can come later.
  72.      */
  73.     /*
  74.      * This doesn't work for longlines, because it recalculates
  75.      * the row from a starting position of the current row, and
  76.      * so adds (c_line_size - 1) to the row:
  77.     calc_position_in_line(win);
  78.      * so we just call cursupdate() instead.
  79.      */
  80.     win->w_curs_new = TRUE;
  81. }
  82.  
  83. static void
  84. calc_position_in_line(win)
  85. Xviwin    *win;
  86. {
  87.     register Posn    *curp;
  88.     register int    c;
  89.     register int    i;
  90.     register unsigned    width;
  91.     register int    ccol;
  92.  
  93.     curp = win->w_cursor;
  94.  
  95.     /*
  96.      * Work out the virtual column within the current line.
  97.      */
  98.     ccol = Pb(P_number) ? NUM_SIZE : 0;
  99.     for (i = width = 0; i <= curp->p_index; i++) {
  100.  
  101.     c = curp->p_line->l_text[i];
  102.     ccol += width;
  103.     width = vischar(c, (char **) NULL, ccol);
  104.     }
  105.  
  106.     if (State != INSERT && c == '\t' && ! Pb(P_list) && Pb(P_tabs)) {
  107.     /*
  108.      * If we are inserting, or we're on a control
  109.      * character other than a tab, or we aren't showing
  110.      * tabs normally, the cursor goes to the first column
  111.      * of the control character representation: otherwise,
  112.      * if it's a tab & we aren't in insert mode, we place
  113.      * the cursor on the last column of the tab
  114.      * representation. (This is like the "real" vi.)
  115.      */
  116.     ccol += width - 1;
  117.     }
  118.  
  119.     /*
  120.      * If showing line numbers, adjust the virtual column within the line.
  121.      */
  122.     win->w_virtcol = ccol - (Pb(P_number) ? NUM_SIZE : 0);
  123.  
  124.     /*
  125.      * Convert virtual column to screen column by line folding.
  126.      */
  127.     while (ccol >= win->w_ncols) {
  128.     win->w_row++;
  129.     ccol -= win->w_ncols;
  130.     }
  131.     win->w_col = ccol;
  132.  
  133.     /*
  134.      * Don't go past bottom line of window. (This should only
  135.      * happen on a longline which is too big to fit in the
  136.      * window.)
  137.      */
  138.     if (win->w_row >= win->w_nrows - 1) {
  139.     win->w_row = win->w_nrows - 2;
  140.     }
  141.  
  142.     if (win->w_set_want_col) {
  143.     win->w_curswant = win->w_virtcol;
  144.     win->w_set_want_col = FALSE;
  145.     }
  146. }
  147.